package com.ims.equation.server;

import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

import javax.imageio.ImageIO;

import org.apache.commons.codec.binary.Base64;
import org.scilab.forge.jlatexmath.TeXConstants;
import org.scilab.forge.jlatexmath.TeXFormula;


public enum LatexRenderer {

	INSTANCE;

	public static final String STANDARD_FORMAT = "png";
	
	/**
	 * Returns a String which represents a base64 coded rendered picture of the passed LaTex notation.
	 * 
	 * <p>The returned picture is the standard picture format defined by {@link #STANDARD_FORMAT} </p>
	 *  
	 * @param pLatexTag		LaTex notation
	 * @param pSize			size of the picture in pixel
	 * @return the base64 encoded picture
	 */
	public static String base64EncodeLaTexNotation(String pLatexTag, float pSize){
		return base64EncodeImage(renderFormula(pLatexTag, pSize) , STANDARD_FORMAT);
	}
	
	/**
	 * Returns a String which represents a base64 coded rendered picture of the passed LaTex notation.
	 * 
	 * @param pLatexTag		LaTex notation
	 * @param pSize			size of the picture in pixel
	 * @param pPictureFormat the defined picture format
	 * 
	 * @return the base64 encoded picture
	 */
	public static String base64EncodeLaTexNotation(String pLatexTag, float pSize, String pPictureFormat){
		return base64EncodeImage(renderFormula(pLatexTag, pSize), pPictureFormat);
	}
	
	
	/**
	 * Encodes the passed picture into a base64 coded html image tag.
	 * 
	 * @param pImage			the image which is encoded
	 * @param pPictureFormat	the format of the picture
	 * @return the html-image tag with the base64 encoded picture
	 */
	public static String base64EncodeImage(BufferedImage pImage, String pPictureFormat){
		try {
			String url = "<img src= data:image/" + pPictureFormat + ";base64,";			
			ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
			ImageIO.write(pImage, pPictureFormat, outputStream);
			
			String base64encodedImage = new String (Base64.encodeBase64(outputStream.toByteArray()));
			
			return url + base64encodedImage + " />";
			
	     } catch (IOException ex) {
	         System.err.println("Cannot write passed image into the outputStream.");
	         throw new RuntimeException("Cannot encode the passed image.", ex);
	     }
	}
	
	/**
	 * Render the passed LaTex notation into a {@link BufferedImage}.
	 * 
	 * @param pFormula	the LaTex notation
	 * @param size		the size of the picture in pixel.
	 * 
	 * @return the rendered image
	 */
	public static BufferedImage renderFormula(String pFormula, float size ){
		return (BufferedImage) TeXFormula.createBufferedImage(pFormula, TeXConstants.STYLE_DISPLAY, size, null, null);
	}
}
